package com.vardhan.teja.dashclock.gmailextension;


import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.prefs.PreferenceChangeEvent;
import java.util.prefs.PreferenceChangeListener;

import com.vardhan.teja.dashclock.gmailextension.CustomGmail.LabelsQuery;

import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
import android.database.SQLException;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.MultiSelectListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.support.v4.util.LogWriter;
import android.util.Log;
import android.view.MenuItem;

public class SettingsActivity extends PreferenceActivity {
	
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		getActionBar().setIcon(R.drawable.ic_extension_gmail_custom);
		getActionBar().setDisplayHomeAsUpEnabled(true);
		addPreferencesFromResource(R.xml.preferences);
		addAccountPreferences();
		addAllLabelPrefernces();
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == android.R.id.home) {
			// TODO: if the previous activity on the stack isn't a ConfigurationActivity,
			// launch it.
			finish();
			return true;
		}

		return super.onOptionsItemSelected(item);
	}
	 
	private void addAccountPreferences() {
		SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
		String[] accounts = CustomGmail.getAllAccountNames(this);
		Set<String> allAccountsSet = new HashSet<String>();
		allAccountsSet.addAll(Arrays.asList(accounts));
		Set<String> accountsSelected = CustomGmail.getSelectedAccounts(this);
		
		//checks if the account stored in SharedPrefernces still exists on the user device.
		//If the account is removed from the device then it will also be removed from app data.
		if(accountsSelected.size() > 0)
		{
			for(String account : accountsSelected)
			{
				if(!allAccountsSet.contains(account))
				{
					accountsSelected.remove(account);
					sp.edit().remove(account);
				}
			}
			sp.edit().putStringSet(CustomGmail.PREF_ACCOUNTS, accountsSelected).commit();
		}
		
		//deletes the selected labels data from the app data
		if(accountsSelected.size() == 0)
		{
			for(String account : allAccountsSet)
			{
				if(sp.contains(account))
				{
					sp.edit().remove(account).commit();
				}
			}
		}

		MultiSelectListPreference accountsPreference = new MultiSelectListPreference(this);
		accountsPreference.setKey(CustomGmail.PREF_ACCOUNTS);
		accountsPreference.setTitle(R.string.gmail_accounts_title);
		accountsPreference.setEntries(accounts);
		accountsPreference.setEntryValues(accounts);
		accountsPreference.setDefaultValue(allAccountsSet);
		getPreferenceScreen().addPreference(accountsPreference);

		AccountsChangeListener accountsChangeListener = new AccountsChangeListener(accountsSelected, accounts.length);

		accountsPreference.setOnPreferenceChangeListener(accountsChangeListener);
		
		accountsChangeListener.onPreferenceChange(accountsPreference,
				PreferenceManager
				.getDefaultSharedPreferences(this)
				.getStringSet(accountsPreference.getKey(), allAccountsSet));
	}
	
	private void removeaccount(String account)
	{
		SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
		sp.edit().remove(account).commit();
	}
	
	private void addAllLabelPrefernces(){
		
		Set<String> accountsSelected = CustomGmail.getSelectedAccounts(this);
		for(String account : accountsSelected)
		{
			addLabelPreferences(account);
		}
	}
	
	private void addLabelPreferences(String account)
	{
			String[] labels = getAllLabels(account);
			SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
			Set<String> defaultLabels = getInbox(account);
			Set<String> selectedLabels = sp.getStringSet(account, defaultLabels);
			
			MultiSelectListPreference labelspreference = new MultiSelectListPreference(this);
			labelspreference.setKey(account);
			labelspreference.setTitle(account);
			labelspreference.setEntries(labels);
			labelspreference.setEntryValues(labels);
			labelspreference.setDefaultValue(defaultLabels);
			labelspreference.setSummary(R.string.gmail_labels_summary);
			
			getPreferenceScreen().addPreference(labelspreference);
			
			LabelsChangeListener labelsChangeListener = new LabelsChangeListener();
			labelspreference.setOnPreferenceChangeListener(labelsChangeListener);
			labelsChangeListener.onPreferenceChange(labelspreference,selectedLabels);
	}
	
	private String[] getAllLabels(String account){
		Cursor cursor = openLabelsCursor(account);
		Set<String> labelset = new HashSet<String>();
		
		if (cursor == null || cursor.isAfterLast()) {
            
            if (cursor != null) {
                cursor.close();
            }
        }

        while (cursor.moveToNext()) {
            labelset.add(cursor.getString(LabelsQuery.NAME));
        }
        
        cursor.close();
        
        String[] labels = new String[labelset.size()];
        
        return labelset.toArray(labels);
	}
	
	private Set<String> getInbox(String account){
		Cursor cursor = openLabelsCursor(account);
		Set<String> name = new HashSet<String>();
		
		if (cursor == null || cursor.isAfterLast()) {
            
            if (cursor != null) {
                cursor.close();
            }
        }

        while (cursor.moveToNext()) {
            if(GmailContract.Labels.LabelCanonicalNames.CANONICAL_NAME_INBOX.equals(cursor.getString(LabelsQuery.CANONICAL_NAME)))
            {
            	name.add(cursor.getString(LabelsQuery.NAME));
            	break;
            }
        }
        
        cursor.close();
        
        return name;
	}
	
	private Cursor openLabelsCursor(String account) {
        try {
            return getContentResolver().query(
                    GmailContract.Labels.getLabelsUri(account),
                    LabelsQuery.PROJECTION,
                    null, // NOTE: the Labels API doesn't allow selections here
                    null,
                    null);

        } catch (SecurityException e) {
            // From developer console: "Permission Denial: opening provider com.google.android.gsf..
            return null;

        } catch (SQLException e) {
            // From developer console: "SQLiteException: no such table: labels"
            return null;
        }
    }
	
	private class AccountsChangeListener implements OnPreferenceChangeListener
	{

		private Set<String> accountsSelected;
		private int accountsLength;
		
		public AccountsChangeListener(Set<String> accountsSelected, int accountslength)
		{
			this.accountsSelected = accountsSelected;
			this.accountsLength = accountslength;
		}
		
		@Override
		public boolean onPreferenceChange(Preference preference, Object newValue)
		{
			int numSelected = 0;
			int numTotal = accountsLength;


			try {
				//noinspection unchecked
				Set<String> selectedAccounts = (Set<String>) newValue;
				if (selectedAccounts != null) {
					numSelected = selectedAccounts.size();
				}
				Set<String> totalAccounts = new HashSet<String>(selectedAccounts);
				totalAccounts.addAll(accountsSelected);
				for(String account : totalAccounts)
				{
					if(!selectedAccounts.contains(account))
					{
						Preference pref = findPreference(account);
						getPreferenceScreen().removePreference(pref);
						removeaccount(account);
						
					}
					else if(!accountsSelected.contains(account))
					{
						addLabelPreferences(account);
					}
				}
				accountsSelected.addAll(selectedAccounts);
				accountsSelected.retainAll(selectedAccounts);
			}
			
			catch (ClassCastException ignored) {
			}

			preference.setSummary(getResources().getQuantityString(
					R.plurals.gmail_accounts_selected,
					numTotal, numSelected, numTotal));
			return true;
		}
		
	}
	
	private class LabelsChangeListener implements OnPreferenceChangeListener
	{

		@Override
		public boolean onPreferenceChange(Preference preference, Object newValue)
		{
			String summary = "";
			
			try{
				Set<String> selectedLabels = (Set<String>) newValue;
				
				for(String label : selectedLabels)
				{
					summary += label + ", ";
				}
				summary = summary.substring(0, summary.length() - 2);
			}
			catch (ClassCastException e) {
				
			}
			
			preference.setSummary(summary);
			return true;
		}
		
	}
}
